package com.yangye.niodemo.rpc.transport;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;
import java.util.Random;

/**
 * @author yangye
 * @date 2020/12/29
 */
public class ClientPool {

	NioSocketChannel[] clients;

	Object[] locks;

	Random random = new Random();

	public static final int POOL_SIZE = 10;

	public ClientPool() {
		clients = new NioSocketChannel[POOL_SIZE];// 初始化连接池大小
		locks = new Object[POOL_SIZE];

		for (int i = 0; i < POOL_SIZE; i++) {
			locks[i] = new Object();
		}
		System.out.println("初始化连接池...");
	}

	public NioSocketChannel chooseClient() {
		int index = random.nextInt(POOL_SIZE);
		NioSocketChannel client = clients[index];
		if (client != null && client.isActive()) {
			return client;
		}
		synchronized (locks[index]) {
			client = clients[index];
			// 初始化一个client
			if (client == null || !client.isActive()) {
				client = create();
				clients[index] = client;
			}
			return client;
		}
	}

	public NioSocketChannel create() {
		NioEventLoopGroup worker = new NioEventLoopGroup(1);
		Bootstrap b = new Bootstrap();
		b.group(worker)
				.channel(NioSocketChannel.class)
				.handler(new ChannelInitializer<NioSocketChannel>() {
					@Override
					protected void initChannel(NioSocketChannel channel) throws Exception {
						ChannelPipeline p = channel.pipeline();
						p.addLast(new ClientDecoder());
						p.addLast(new ClientHandler());
					}
				});
		ChannelFuture connect = b.connect(new InetSocketAddress("localhost", 9090));
		Channel client;
		try {
			client = connect.sync().channel();
			return (NioSocketChannel) client;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return null;

	}


}
